home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Demos / OOFILE / Buildable, limited OOFILE / OOFILE partial source / oof4.cpp < prev    next >
Encoding:
Text File  |  1995-09-26  |  19.7 KB  |  1,021 lines  |  [TEXT/CWIE]

  1. // COPYRIGHT 1994 A.D. Software, All rights reserved
  2.  
  3. // OOFILE database field-related classes
  4. // numeric fields - see also oof3.cpp
  5.  
  6. #include "oof2.hpp"
  7. #include "oof4.hpp"
  8. #include "oofquery.hpp"  
  9. #include "oofrel.hpp" 
  10.  
  11. extern "C" {
  12. #include <time.h>  // for dbDate stuff
  13. }
  14.  
  15. // define static variables
  16. dbDate::dateFieldOrder dbDate::sDefaultDateOrder=orderDMY;
  17.  
  18.  
  19. // -------------------------------------------------------
  20. //               d b N u m e r i c F i e l d  
  21. // -------------------------------------------------------
  22.  
  23. dbQueryTrinary    dbNumericField::between(long fromNum, long toNum) const
  24. {
  25.     return dbQueryTrinary(new dbQueryField(this), dbQueryClause::between,
  26.         MakeQueryLiteral(fromNum), MakeQueryLiteral(toNum));
  27. }
  28.  
  29.  
  30. dbQueryTrinary    dbNumericField::outside(long fromNum, long toNum) const
  31. {
  32.     return dbQueryTrinary(new dbQueryField(this), dbQueryClause::outside,
  33.         MakeQueryLiteral(fromNum), MakeQueryLiteral(toNum));
  34. }
  35.  
  36.  
  37. dbQueryBinary    dbNumericField::operator==(long n) const
  38. {
  39.     return dbQueryBinary(new dbQueryField(this), dbQueryClause::equals, MakeQueryLiteral(n));
  40. }    
  41.  
  42.  
  43. dbQueryBinary    dbNumericField::operator!=(long n) const
  44. {
  45.     return dbQueryBinary(new dbQueryField(this), dbQueryClause::notEquals, MakeQueryLiteral(n));
  46. }  
  47.  
  48.  
  49. dbQueryBinary    dbNumericField::operator<(long n) const
  50. {
  51.     return dbQueryBinary(new dbQueryField(this), dbQueryClause::lessThan, MakeQueryLiteral(n));
  52. }  
  53.  
  54.  
  55. dbQueryBinary    dbNumericField::operator<=(long n) const
  56. {
  57.     return dbQueryBinary(new dbQueryField(this), dbQueryClause::lessThanOrEqual, MakeQueryLiteral(n));
  58. }  
  59.  
  60.  
  61. dbQueryBinary    dbNumericField::operator>(long n) const
  62. {
  63.     return dbQueryBinary(new dbQueryField(this), dbQueryClause::greaterThan, MakeQueryLiteral(n));
  64. }  
  65.  
  66.  
  67. dbQueryBinary    dbNumericField::operator>=(long n) const
  68. {
  69.     return dbQueryBinary(new dbQueryField(this), dbQueryClause::greaterThanOrEqual, MakeQueryLiteral(n));
  70. }  
  71.  
  72.  
  73. void dbNumericField::operator/=(long rhs)
  74.  
  75. {
  76. // NOT YET IMPLEMENTED
  77. }
  78.  
  79.  
  80.  
  81. void dbNumericField::operator-=(long rhs)
  82.  
  83. {
  84. // NOT YET IMPLEMENTED
  85. }
  86.  
  87.  
  88.  
  89. void dbNumericField::operator+=(long rhs)
  90.  
  91. {
  92. // NOT YET IMPLEMENTED
  93. }
  94.  
  95.  
  96.  
  97. void dbNumericField::operator*=(long rhs)
  98.  
  99. {
  100. // NOT YET IMPLEMENTED
  101. ;
  102. }
  103.  
  104.  
  105. void dbNumericField::operator/=(double rhs)
  106.  
  107. {
  108. // NOT YET IMPLEMENTED
  109. }
  110.  
  111.  
  112.  
  113. void dbNumericField::operator-=(double rhs)
  114.  
  115. {
  116. // NOT YET IMPLEMENTED
  117. }
  118.  
  119.  
  120.  
  121. void dbNumericField::operator+=(double rhs)
  122.  
  123. {
  124. // NOT YET IMPLEMENTED
  125. }
  126.  
  127.  
  128.  
  129. void dbNumericField::operator*=(double rhs)
  130.  
  131. {
  132. // NOT YET IMPLEMENTED
  133. ;
  134. }
  135.  
  136.  
  137.  
  138. void dbNumericField::CheckRange(double d, long minL, long maxL, const char* file, int line)
  139. {
  140.     if (d<minL) {
  141.         dbConnect::raise(ostrstream() << file << "line: " << line <<
  142.         "Range conversion error: double " << d 
  143.         << " below min of " << minL << endl);
  144.     }
  145.     else
  146.         if (d>maxL) {
  147.             dbConnect::raise(ostrstream() << file << "line: " << line <<
  148.             "Range conversion error: double " << d 
  149.             << " above max of " << maxL << endl);
  150.         }
  151. }
  152.  
  153.  
  154.  
  155. void dbNumericField::CheckRange(long l, long min, long max, const char* file, int line)
  156. {
  157.     if (l<min) {
  158.         dbConnect::raise(ostrstream() << file << "line: " << line <<
  159.         "Range conversion error: long " << l 
  160.         << " below min of " << min << endl);
  161.     }
  162.     else
  163.         if (l>max) {
  164.             dbConnect::raise(ostrstream() << file << "line: " << line <<
  165.             "Range conversion error: long " << l 
  166.             << " above max of " << max << endl);
  167.         }
  168. }
  169.  
  170.  
  171. void dbNumericField::CheckRange(unsigned long l, unsigned long max, const char* file, int line)
  172. {
  173.     if (l>max) {
  174.         dbConnect::raise(ostrstream() << file << "line: " << line <<
  175.         "Range conversion error: ulong " << l 
  176.         << " above max of " << max << endl);
  177.     }
  178. }
  179.  
  180.  
  181. dbQueryLiteral* dbNumericField::MakeQueryLiteral(long n) const
  182. {
  183.     return new dbQueryLiteralLong(n);
  184. }
  185.  
  186.  
  187. // -------------------------------------------------------
  188. //                   d b S h o r t
  189. // -------------------------------------------------------
  190. dbShort& dbShort::operator=(dbShort& rhs)
  191. {
  192.     if (this == &rhs)
  193.         return *this;
  194.     
  195.     *this = (short)rhs;
  196.     return *this;
  197. }
  198.  
  199.  
  200. void dbShort::setString(const char* str)
  201. {
  202.     short n;
  203.     istrstream is((char*)str);  // cast away const for Borland
  204.     is >> n;
  205.     *this = n;
  206. }
  207.  
  208.  
  209. dbShort::operator short()
  210. {
  211.     validateContextInCaseRelated();
  212.     short *readFrom = (short *)mBackend->getFieldReadFrom(mFieldNumber);
  213.     return *readFrom;
  214. }
  215.  
  216.  
  217. dbShort& dbShort::operator=(short n)
  218. {
  219.     validateContextInCaseRelated();
  220.     short *writeTo = (short *)mBackend->getFieldWriteDest(mFieldNumber);
  221.     if (writeTo)
  222.         *writeTo = n;    
  223.     mBackend->markDirty();
  224.     return *this;
  225. }
  226.  
  227.  
  228. OOF_fieldTypes dbShort::fieldType() const
  229. {
  230.     return shortField;
  231. }
  232.  
  233.  
  234. unsigned long dbShort::fieldLen() const
  235. {
  236.     return sizeof(short); 
  237. }
  238.  
  239.  
  240. void dbShort::extract(ostream& os)
  241. {
  242.     validateContextInCaseRelated();
  243.     short *readFrom = (short *) mBackend->getFieldReadFrom(mFieldNumber);
  244.     os << *readFrom;
  245. }
  246.  
  247.  
  248. void dbShort::generateTestData(const char *ignored , unsigned long ignoredLen)
  249. {
  250.     *this = (short)(rand()-rand()/2);
  251. }
  252.  
  253.  
  254. dbShort& dbShort::operator()()
  255. {
  256.     dbShort* retField = (dbShort*) GetRelatedFieldOrUs();
  257.     return *retField;
  258. }
  259.  
  260.  
  261. dbQueryLiteral* dbShort::MakeQueryLiteral(long n) const
  262. {
  263.     return new dbQueryLiteralShort((short)n);
  264. }
  265.  
  266.  
  267. // -------------------------------------------------------
  268. //                   d b U s h o r t
  269. // -------------------------------------------------------
  270. dbUshort& dbUshort::operator=(dbUshort& rhs)
  271. {
  272.     if (this == &rhs)
  273.         return *this;
  274.     
  275.     *this = (unsigned short)rhs;
  276.     return *this;
  277. }
  278.  
  279.  
  280. void dbUshort::setString(const char* str)
  281. {
  282.     unsigned short n;
  283.     istrstream is((char*)str);  // cast away const for Borland
  284.     is >> n;
  285.     *this = n;
  286. }
  287.  
  288.  
  289. dbUshort::operator unsigned short()
  290. {
  291.     validateContextInCaseRelated();
  292.     unsigned short *readFrom = (unsigned short *)mBackend->getFieldReadFrom(mFieldNumber);
  293.     return *readFrom;
  294. }
  295.  
  296.  
  297. dbUshort& dbUshort::operator=(unsigned short n)
  298. {
  299.     validateContextInCaseRelated();
  300.     unsigned short *writeTo = (unsigned short *)mBackend->getFieldWriteDest(mFieldNumber);
  301.     if (writeTo)
  302.         *writeTo = n;    
  303.     mBackend->markDirty();
  304.     return *this;
  305. }
  306.  
  307.  
  308. OOF_fieldTypes dbUshort::fieldType() const
  309. {
  310.     return uShortField;
  311. }
  312.  
  313.  
  314. unsigned long dbUshort::fieldLen() const
  315. {
  316.     return sizeof(unsigned short); 
  317. }
  318.  
  319.  
  320. void dbUshort::extract(ostream& os)
  321. {
  322.     validateContextInCaseRelated();
  323.     unsigned short *readFrom = (unsigned short *) mBackend->getFieldReadFrom(mFieldNumber);
  324.     os << *readFrom;
  325. }
  326.  
  327.  
  328. void dbUshort::generateTestData(const char *ignored , unsigned long ignoredLen)
  329. {
  330.     *this = (unsigned short)(rand());
  331. }
  332.  
  333.  
  334. dbUshort& dbUshort::operator()()
  335. {
  336.     dbUshort* retField = (dbUshort*) GetRelatedFieldOrUs();
  337.     return *retField;
  338. }
  339.  
  340.  
  341. dbQueryLiteral* dbUshort::MakeQueryLiteral(long n) const
  342. {
  343.     return new dbQueryLiteralUshort((unsigned short)n);
  344. }
  345.  
  346.  
  347. // -------------------------------------------------------
  348. //                      d b L o n g
  349. // -------------------------------------------------------
  350. dbLong& dbLong::operator=(dbLong& rhs)
  351. {
  352.     if (this == &rhs)
  353.         return *this;
  354.     
  355.     *this = (long)rhs;
  356.     return *this;
  357. }
  358.  
  359.  
  360. dbLong& dbLong::operator=(long n)
  361. {
  362.         validateContextInCaseRelated();
  363.         long *writeTo = (long *)mBackend->getFieldWriteDest(mFieldNumber);
  364.         if (writeTo)
  365.             *writeTo = n;    
  366.     mBackend->markDirty();
  367.     return *this;
  368. }
  369.  
  370.  
  371. void dbLong::setString(const char* str)
  372. {
  373.     long n;
  374.     istrstream is((char*)str);  // cast away const for Borland
  375.     is >> n;
  376.     *this = n;
  377. }
  378.  
  379.  
  380. dbLong::operator long()
  381. {
  382.     validateContextInCaseRelated();
  383.     long *readFrom = (long *)mBackend->getFieldReadFrom(mFieldNumber);
  384.     return *readFrom;
  385. }
  386.  
  387.  
  388. void dbLong::copyValueFrom(dbField* srcField)
  389. {
  390.     if (srcField->fieldType()==longField)
  391.         dbLong::operator=( (long)(*(dbLong*)srcField));  // safe downcast
  392. #ifdef OOF_Debug
  393.     else
  394.         dbConnect::raise(ostrstream() << "wrong field type passed in to dbLong::copyValueFrom, copying to " << fieldName() << " from " << srcField->fieldName());
  395. #endif
  396. }
  397.  
  398.  
  399. OOF_fieldTypes dbLong::fieldType() const
  400. {
  401.     return longField; 
  402. }
  403.  
  404.  
  405. unsigned long dbLong::fieldLen() const
  406. {
  407.     return sizeof(long); 
  408. }
  409.  
  410.  
  411. void dbLong::extract(ostream& os)
  412. {
  413.     validateContextInCaseRelated();
  414.     long *readFrom = (long *) mBackend->getFieldReadFrom(mFieldNumber);
  415.     os << *readFrom;
  416. }
  417.  
  418.  
  419. void dbLong::generateTestData(const char *ignored , unsigned long ignoredLen)
  420. {
  421.     *this = (rand()-rand());
  422. }
  423.  
  424.  
  425. dbLong& dbLong::operator()()
  426. {
  427.     dbLong* retField = (dbLong*) GetRelatedFieldOrUs();
  428.     return *retField;
  429. }
  430.  
  431.  
  432. // -------------------------------------------------------
  433. //                      d b U l o n g
  434. // -------------------------------------------------------
  435. dbUlong& dbUlong::operator=(dbUlong& rhs)
  436. {
  437.     if (this == &rhs)
  438.         return *this;
  439.     
  440.     *this = (unsigned long)rhs;
  441.     return *this;
  442. }
  443.  
  444.  
  445. dbUlong& dbUlong::operator=(unsigned long n)
  446. {
  447.         validateContextInCaseRelated();
  448.         unsigned long *writeTo = (unsigned long *)mBackend->getFieldWriteDest(mFieldNumber);
  449.         if (writeTo)
  450.             *writeTo = n;    
  451.     mBackend->markDirty();
  452.     return *this;
  453. }
  454.  
  455.  
  456. void dbUlong::setString(const char* str)
  457. {
  458.     unsigned long n;
  459.     istrstream is((char*)str);  // cast away const for Borland
  460.     is >> n;
  461.     *this = n;
  462. }
  463.  
  464.  
  465. dbUlong::operator unsigned long()
  466. {
  467.     validateContextInCaseRelated();
  468.     unsigned long *readFrom = (unsigned long *)mBackend->getFieldReadFrom(mFieldNumber);
  469.     return *readFrom;
  470. }
  471.  
  472.  
  473. void dbUlong::copyValueFrom(dbField* srcField)
  474. {
  475.     if (srcField->fieldType()==uLongField)
  476.         dbUlong::operator=( (unsigned long)(*(dbUlong*)srcField));  // safe downcast
  477. #ifdef OOF_Debug
  478.     else
  479.         dbConnect::raise(ostrstream() << "wrong field type passed in to dbUlong::copyValueFrom, copying to " << fieldName() << " from " << srcField->fieldName());
  480. #endif
  481. }
  482.  
  483.  
  484. OOF_fieldTypes dbUlong::fieldType() const
  485. {
  486.     return uLongField; 
  487. }
  488.  
  489.  
  490. unsigned long dbUlong::fieldLen() const
  491. {
  492.     return sizeof(unsigned long); 
  493. }
  494.  
  495.  
  496. void dbUlong::extract(ostream& os)
  497. {
  498.     validateContextInCaseRelated();
  499.     unsigned long *readFrom = (unsigned long *) mBackend->getFieldReadFrom(mFieldNumber);
  500.     os << *readFrom;
  501. }
  502.  
  503.  
  504. void dbUlong::generateTestData(const char *ignored , unsigned long ignoredLen)
  505. {
  506.     *this = (unsigned long)rand();
  507. }
  508.  
  509.  
  510. dbQueryLiteral* dbUlong::MakeQueryLiteral(unsigned long n) const
  511. {
  512.     return new dbQueryLiteralUlong(n);
  513. }
  514.  
  515.  
  516. dbQueryLiteral* dbUlong::MakeQueryLiteral(long n) const
  517. {
  518.     return new dbQueryLiteralUlong((unsigned long) n);
  519. }
  520.  
  521.  
  522. dbUlong& dbUlong::operator()()
  523. {
  524.     dbUlong* retField = (dbUlong*) GetRelatedFieldOrUs();
  525.     return *retField;
  526. }
  527.  
  528.  
  529. dbQueryBinary    dbUlong::operator==(unsigned long n) const
  530. {
  531.     return dbQueryBinary(new dbQueryField(this), dbQueryClause::equals, MakeQueryLiteral(n));
  532. }
  533.  
  534.  
  535. // -------------------------------------------------------
  536. //                      d b D a t e
  537. // -------------------------------------------------------
  538. dbDate::~dbDate()
  539. {
  540.     delete[] mStrBuffer;
  541. }
  542.  
  543.  
  544. unsigned long dbDate::fieldLen() const
  545. {
  546.     return sizeof(long); 
  547. }
  548.  
  549. OOF_fieldTypes dbDate::fieldType() const
  550. {
  551.     return dateField; 
  552. }
  553.  
  554.  
  555. void dbDate::extract(ostream& os)
  556. {
  557.     long binDate = (long)*this;
  558.     short day, month, year;
  559.     long2ymd(binDate, year, month, day);
  560.     ymd2Stream(year, month, day, os);
  561. }
  562.  
  563.  
  564. ostream& dbDate::today(ostream& os)
  565. {
  566.     short day, month, year;
  567.     today2ymd(year, month, day);
  568.     return ymd2Stream(year, month, day, os);
  569. }
  570.  
  571.  
  572. ostream& dbDate::ymd2Stream(short year, short month, short day, ostream& os)
  573. {
  574.     switch (sDefaultDateOrder) {
  575.     case orderYMD :
  576.         os << year << "/" << month << "/" << day;
  577.         break;
  578.         
  579.     case orderDMY : 
  580.         os << day << "/" << month << "/" << year;
  581.         break;
  582.         
  583.     case orderMDY : 
  584.         os << month << "/" << day << "/" << year;
  585.         break;
  586.     }
  587.     return os;
  588. }
  589.  
  590.  
  591. void dbDate::generateTestData(const char *ignored , unsigned long ignoredLen)
  592. {
  593. //    const long startDate = ymd2Long(1963, 5, 7);
  594. //    const long endDate = ymd2Long(2001,1,1);
  595. //    const long dateDiff = endDate - startDate;
  596. //    setDate(startDate);
  597. //  operator+=(rand()%dateDiff);   // don't have this operator yet!
  598.  
  599. // pretty sick alternative but at least it generates legal dates
  600.     setDate(ymd2Long( (rand()%(2010-1963) + 1963),
  601.                       (rand()%12), (rand()%28) ));
  602. }
  603.  
  604.  
  605. dbQueryTrinary    dbDate::between(const char* fromStr, const char* toStr) const
  606. {
  607.     return dbNumericField::between(chars2Long(fromStr), chars2Long(toStr));
  608. }
  609.  
  610.  
  611. dbQueryTrinary    dbDate::outside(const char* fromStr, const char* toStr) const
  612. {
  613.     return dbNumericField::outside(chars2Long(fromStr), chars2Long(toStr));
  614. }
  615.  
  616.  
  617. dbQueryBinary    dbDate::operator==(const char* str) const
  618. {
  619.     return dbNumericField::operator==(chars2Long(str));
  620. }    
  621.  
  622.  
  623. dbQueryBinary    dbDate::operator!=(const char* str) const
  624. {
  625.     return dbNumericField::operator!=(chars2Long(str));
  626. }  
  627.  
  628.  
  629. dbQueryBinary    dbDate::operator<(const char* str) const
  630. {
  631.     return dbNumericField::operator<(chars2Long(str));
  632. }  
  633.  
  634.  
  635. dbQueryBinary    dbDate::operator<=(const char* str) const
  636. {
  637.     return dbNumericField::operator<=(chars2Long(str));
  638. }  
  639.  
  640.  
  641. dbQueryBinary    dbDate::operator>(const char* str) const
  642. {
  643.     return dbNumericField::operator>(chars2Long(str));
  644. }  
  645.  
  646.  
  647. dbQueryBinary    dbDate::operator>=(const char* str) const
  648. {
  649.     return dbNumericField::operator>=(chars2Long(str));
  650. }  
  651.  
  652.  
  653. dbDate& dbDate::operator=(const char* str)
  654. {
  655.     short day, month, year;
  656.     chars2ymd(str, year, month, day);
  657.     setDate(year, month, day);
  658.     return *this;
  659. }
  660.  
  661.  
  662. dbDate& dbDate::operator=(dbDate& rhs)
  663. {
  664.     if (this == &rhs)
  665.         return *this;
  666.     
  667.     setDate((long)rhs);
  668.     return *this;
  669. }
  670.  
  671.  
  672. void dbDate::setDate(long n)
  673. {
  674.     validateContextInCaseRelated();
  675.     long *writeTo = (long *)mBackend->getFieldWriteDest(mFieldNumber);
  676.     if (writeTo)
  677.         *writeTo = n;    
  678.     mBackend->markDirty();
  679. }
  680.  
  681.  
  682. dbDate::operator const char*()
  683. {
  684.     delete[] mStrBuffer;  // it's just a temp buffer to give us something to return a pointer to
  685.     mStrBuffer = copyAsChars();
  686.     return mStrBuffer;
  687. }
  688.  
  689.  
  690. #ifdef _Macintosh
  691. void dbDate::asStr255(Str255 s) 
  692. {
  693.     delete[] mStrBuffer;  // it's just a temp buffer to give us something to return a pointer to
  694.     mStrBuffer = copyAsChars();
  695.     s[0] = strlen(mStrBuffer);
  696.     memcpy(s+1, mStrBuffer, s[0]);
  697. #ifdef OOF_SmartHeap
  698.     MemPoolCheck(MemDefaultPool);
  699. #endif
  700. }
  701.  
  702.  
  703. void dbDate::setStr255(const Str255 s)
  704. {
  705.     const char* strStart = (char*) s+1;
  706.     dbDate::operator=(strStart);
  707. }
  708.  
  709.  
  710.  
  711. // end of Mac-specific extra conversions
  712. #endif
  713.  
  714.  
  715. dbDate::operator long()
  716. {
  717.     validateContextInCaseRelated();
  718.     long *readFrom = (long *)mBackend->getFieldReadFrom(mFieldNumber);
  719.     return *readFrom;
  720. }
  721.  
  722.  
  723. void dbDate::setDate(short year, short month, short day)
  724. {
  725.     long binDate = ymd2Long(year, month, day);
  726.     setDate(binDate);
  727. }
  728.  
  729.  
  730. void dbDate::setDateToSystemDate()
  731. {
  732.     short year, month, day;
  733.     today2ymd(year, month, day);
  734.     setDate(year, month, day);
  735. }
  736.  
  737.  
  738. void dbDate::getDate(short& year, short& month, short& day)
  739. {
  740.     long binDate = (long) *this;
  741.     long2ymd(binDate, year, month, day);
  742. }
  743.  
  744.  
  745. long dbDate::ymd2Long(short year, short month, short day)
  746. {
  747.     if (checkDate(year, month, day)) {
  748.     if (year<100)
  749.         year += thisCentury();
  750.     return (( ( ((long)year << 8) + (long)month) << 8) + day);    // use discrete bytes for ease of reading
  751.     }
  752.     else {
  753. #ifdef OOF_Debug
  754.         dbConnect::raise(ostrstream() << "Bad date passed to dbDate::ymd2Long: YMD = " << year << month << day);
  755. #endif    
  756.         return 0;
  757.     }
  758. }
  759.  
  760.  
  761. void dbDate::long2ymd(long binaryDate, short& year, short& month, short& day)
  762. {
  763.     day = binaryDate & 0xFF;
  764.     long shifted = binaryDate >> 8;
  765.     month = shifted & 0xFF;
  766.     shifted = shifted >> 8;
  767.     year = shifted;
  768. }
  769.  
  770.  
  771. void dbDate::today2ymd(short& year, short& month, short& day)
  772. {
  773.     time_t numTime = time(0);
  774.     if (numTime == -1) {
  775. #ifdef OOF_Debug
  776.         dbConnect::raise("System time not available");
  777. #endif
  778.         year = month = day = 0;
  779.     }
  780.     else {
  781.         struct tm* timeBits;
  782.         timeBits = localtime(&numTime);
  783.         day = timeBits->tm_mday;
  784.         month = timeBits->tm_mon+1;
  785.         year = timeBits->tm_year+1900;
  786.     }
  787. }
  788.  
  789.  
  790. short dbDate::thisCentury()
  791. {
  792.     time_t numTime = time(0);
  793.     if (numTime == -1) {
  794. #ifdef OOF_Debug
  795.         dbConnect::raise("System time not available");
  796. #endif
  797.         return 1900;  // coarse default
  798.     }
  799.     else {
  800.         struct tm* timeBits;
  801.         timeBits = localtime(&numTime);
  802.         return (timeBits->tm_year/100)*100+1900;
  803.     }
  804. }
  805.  
  806.  
  807. bool dbDate::chars2ymd(const char* str, short& year, short& month, short& day, dateFieldOrder theOrder)
  808. {
  809.     istrstream s((char*)str);
  810.     return istream2ymd(s, year, month, day, theOrder);
  811. }
  812.  
  813.  
  814. long dbDate::chars2Long(const char* str, dateFieldOrder theOrder)
  815. {
  816.     short year, month, day;
  817.     istrstream s((char*)str);
  818.     if (istream2ymd(s, year, month, day, theOrder))
  819.         return ymd2Long(year, month, day);
  820.     else
  821.         return 0;
  822. }
  823.  
  824.  
  825. bool dbDate::istream2ymd(istream& is, short& year, short& month, short& day, dateFieldOrder theOrder)
  826. {
  827. //    if (is.peek()=='\n')
  828. //        return false;  // early exit - empty line
  829.         
  830.     int n1=0, n2=0, n3=0;
  831.     if (!skipTillDigit(is))
  832.         return false;
  833.     is >> n1;
  834.     if (!skipTillDigit(is))
  835.         return false;
  836.     is >> n2;
  837.     if (!skipTillDigit(is))
  838.         return false;
  839.     is >> n3;
  840.     if (is.good()) {
  841.         switch (theOrder) {
  842.         case orderYMD :
  843.             year = n1;
  844.             month = n2;
  845.             day = n3;
  846.             break;
  847.             
  848.         case orderDMY : 
  849.             day = n1;
  850.             month = n2;
  851.             year = n3;
  852.             break;
  853.             
  854.         case orderMDY : 
  855.             month = n1;
  856.             day = n2;
  857.             year = n3;
  858.             break;
  859.             
  860.         
  861.         }
  862.         if (year<100)
  863.             year += thisCentury();
  864.         return checkDate(year, month, day);
  865.     }
  866.     else
  867.         return false;
  868. }
  869.  
  870.  
  871. bool dbDate::checkDate(short year, short month, short day)
  872. {
  873.     if ( (day<1) || (month<1) || (year<1) )
  874.         return false;
  875.     if ( (day>31) || (month>12))
  876.         return false;
  877. // NOT YET IMPLEMENTED - proper date checking
  878.  
  879.     return true;
  880. }
  881.  
  882.  
  883.  
  884. dbDate& dbDate::operator()()
  885. {
  886.     dbDate* retField = (dbDate*) GetRelatedFieldOrUs();
  887.     return *retField;
  888. }
  889.  
  890.  
  891. // -------------------------------------------------------
  892. //                      d b R e a l
  893. // -------------------------------------------------------
  894. dbReal& dbReal::operator=(dbReal& rhs)
  895. {
  896.     if (this == &rhs)
  897.         return *this;
  898.     
  899.     *this = (double)rhs;
  900.     return *this;
  901. }
  902.  
  903.  
  904. dbReal& dbReal::operator=(double n)
  905. {
  906.     validateContextInCaseRelated();
  907.     double *writeTo = (double *)mBackend->getFieldWriteDest(mFieldNumber);
  908.     if (writeTo)
  909.         *writeTo = n;    
  910.     mBackend->markDirty();
  911.     return *this;
  912. }
  913.  
  914.  
  915. void dbReal::setString(const char* str)
  916. {
  917.     double n;
  918.     istrstream is((char*)str);  // cast away const for Borland
  919.     is >> n;
  920.     *this = n;
  921. }
  922.  
  923.  
  924. dbReal::operator double()
  925. {
  926.     validateContextInCaseRelated();
  927.     double *readFrom = (double *)mBackend->getFieldReadFrom(mFieldNumber);
  928.     return *readFrom;
  929. }
  930.  
  931.  
  932. OOF_fieldTypes dbReal::fieldType() const
  933. {
  934.     return realField; 
  935. }
  936.  
  937.  
  938. unsigned long dbReal::fieldLen() const
  939. {
  940.     return sizeof(double); 
  941. }
  942.  
  943.  
  944. void dbReal::extract(ostream& os)
  945. {
  946.     validateContextInCaseRelated();
  947.     double *readFrom = (double *) mBackend->getFieldReadFrom(mFieldNumber);
  948.     os << *readFrom;
  949. }
  950.  
  951.  
  952. void dbReal::generateTestData(const char *ignored , unsigned long ignoredLen)
  953. {
  954.     *this = (1.7*rand()-rand()*1.5);
  955. }
  956.  
  957.  
  958. dbReal& dbReal::operator()()
  959. {
  960.     dbReal* retField = (dbReal*) GetRelatedFieldOrUs();
  961.     return *retField;
  962. }
  963.  
  964.  
  965. dbQueryTrinary    dbReal::between(double fromNum, double toNum) const
  966. {
  967.     return dbQueryTrinary(new dbQueryField(this), dbQueryClause::between,
  968.         new dbQueryLiteralDouble(fromNum), new dbQueryLiteralDouble(toNum));
  969. }
  970.  
  971.  
  972. dbQueryTrinary    dbReal::outside(double fromNum, double toNum) const
  973. {
  974.     return dbQueryTrinary(new dbQueryField(this), dbQueryClause::outside,
  975.         new dbQueryLiteralDouble(fromNum), new dbQueryLiteralDouble(toNum));
  976. }
  977.  
  978.  
  979. dbQueryBinary    dbReal::operator==(double d) const
  980. {
  981.     return dbQueryBinary(new dbQueryField(this), dbQueryClause::equals, new dbQueryLiteralDouble(d));
  982. }  
  983.  
  984.  
  985.  dbQueryBinary    dbReal::operator!=(double d) const
  986. {
  987.     return dbQueryBinary(new dbQueryField(this), dbQueryClause::notEquals, new dbQueryLiteralDouble(d));
  988. }  
  989.  
  990.  
  991.  dbQueryBinary    dbReal::operator<(double d) const
  992. {
  993.     return dbQueryBinary(new dbQueryField(this), dbQueryClause::lessThan, new dbQueryLiteralDouble(d));
  994. }  
  995.  
  996.  
  997.  dbQueryBinary    dbReal::operator<=(double d) const
  998. {
  999.     return dbQueryBinary(new dbQueryField(this), dbQueryClause::lessThanOrEqual, new dbQueryLiteralDouble(d));
  1000. }  
  1001.  
  1002.  
  1003.  dbQueryBinary    dbReal::operator>(double d) const
  1004. {
  1005.     return dbQueryBinary(new dbQueryField(this), dbQueryClause::greaterThan, new dbQueryLiteralDouble(d));
  1006. }  
  1007.  
  1008.  
  1009.  dbQueryBinary    dbReal::operator>=(double d) const
  1010. {
  1011.     return dbQueryBinary(new dbQueryField(this), dbQueryClause::greaterThanOrEqual, new dbQueryLiteralDouble(d));
  1012. }  
  1013.  
  1014.  
  1015. dbQueryLiteral* dbReal::MakeQueryLiteral(long n) const
  1016. {
  1017.     return new dbQueryLiteralDouble(n);
  1018. }
  1019.  
  1020.  
  1021.